import { useEffect, useRef, useState } from 'react'
import style from './music.module.scss'
import { showToast } from '@/utils/toast'
import pianoPlayerEvent from '@/event/pianoPlayerEvent'
import playSvg from '@/assets/svg/play.svg'
import pauseSvg from '@/assets/svg/pause.svg'
import songListEvent from '@/event/songListEvent'
import ProgressBar from '@/components/ProgressBar'
import { musicListStore } from '@/store/musicListStore'
import { observer } from 'mobx-react'
import { MusicPlayerSong } from '@/types/music'
import moreSvg from '@/assets/svg/more-white.svg'
import { showContextMenu } from '@/utils/contextMenu'
import { sleep } from '@/utils/common'
import { MessageBox } from '@/utils/messageBox'
import { exportMidi } from '@/lib/music/ToneMidi'
import { AutoPlaySongController } from '@/lib/music/AutoPlaySongController'
function SongList() {
  const [editNameIndex, setEditNameIndex] = useState<number>(-1)
  const [tmpEditName, setTmpEditName] = useState('')
  const [playerProgress, setPlayerProgress] = useState(0)
  const [playerSongName, setPlayerSongName] = useState('')
  const playerSongController = useRef<AutoPlaySongController | null>(null)
  const [isPause, setIsPause] = useState(false)
  async function playerPusicSong(index: number) {
    if (playerSongName === musicListStore.value.list[index].name) {
      showToast('正在播放中')
      return
    }
    if (playerSongName) {
      playerSongController.current?.stop()
      await sleep(500)
    }
    const song = musicListStore.value.list[index]
    songListEvent.emit('setActiveSong', song)
    setPlayerSongName(song.name)
    pianoPlayerEvent.emit('playerSong', song, playerSongController)
    playerSongController.current?.onEnd(() => {
      playerSongController.current = null
      setPlayerProgress(0)
      setPlayerSongName('')
      songListEvent.emit('setActiveSong', null)
      isEnd = true
    })
    let isEnd = false
    const getProgress = () => {
      if (isEnd) {
        return
      }
      setPlayerProgress(playerSongController.current?.getProgress() || 0)
      setTimeout(getProgress, 200)
    }
    getProgress()
  }
  function stopPusicSong(index: number) {
    if (musicListStore.value.list[index].name !== playerSongName) {
      showToast('error:不是当前播放的乐曲')
      return
    }
    playerSongController.current?.stop()
  }
  function isActive(song: MusicPlayerSong) {
    return song.name == playerSongName
  }
  function showMoreContextMenu(index: number) {
    showContextMenu(
      [
        {
          key: 'rename',
          label: '修改名称',
        },
        {
          key: 'edit',
          label: '编辑音频',
        },
        {
          key: 'exportMid',
          label: '导出MIDI文件',
        },
        {
          key: 'remove',
          label: '删除音频',
        },
      ],
      async (key) => {
        switch (key) {
          case 'rename':
            setTmpEditName(musicListStore.value.list[index].name)
            setEditNameIndex(index)
            break
          case 'edit':
            showToast('敬请期待')
            break
          case 'exportMid':
            try {
              const file = exportMidi(musicListStore.value.list[index])
              const a = document.createElement('a')
              a.href = URL.createObjectURL(file)
              a.download = `${musicListStore.value.list[index].name}.mid`
              a.click()
              showToast('导出成功')
            } catch (e) {
              showToast('导出失败')
            }
            break
          case 'remove':
            const flag = await MessageBox.propt(
              '删除歌曲',
              `确定要删除歌曲 ${musicListStore.value.list[index].name} 吗？`
            )
            if (!flag) return
            musicListStore.value.list.splice(index, 1)
            musicListStore.setValue('list', musicListStore.value.list)
            if (editNameIndex != -1) {
              setEditNameIndex(-1)
            }
            showToast('删除成功')
            break
        }
      }
    )
  }

  useEffect(() => {
    const u1 = songListEvent.on('addSongList', (song) => {
      musicListStore.setValue('list', [song, ...musicListStore.value.list])
    })
    const u2 = pianoPlayerEvent.on('songPause', () => {
      setIsPause(true)
    })
    const u3 = pianoPlayerEvent.on('songReplay', (song) => {
      // setIsPause(false)
      setPlayerSongName((playerSongName) => {
        if (song.name == playerSongName) {
          setIsPause(false)
        }
        return playerSongName
      })
    })
    return () => {
      u1()
      u2()
      u3()
    }
  }, [])
  return (
    <div className={style['song-list']}>
      {musicListStore.value.list.map((song, index) => {
        return (
          <div
            key={song.name}
            className={
              style['song-item'] +
              (playerSongName == song.name
                ? ' ' + style['song-item-active']
                : '')
            }>
            <div style={{ marginRight: 'auto' }}>
              <div className={style['song-name']}>
                {editNameIndex == index ? (
                  <input
                    autoFocus
                    type="text"
                    value={tmpEditName}
                    onChange={(e) => {
                      setTmpEditName(e.target.value)
                    }}
                    onKeyDown={(e) => {
                      if (e.key == 'Enter') {
                        const list = musicListStore.value.list
                        if (list[index].name == playerSongName) {
                          setPlayerSongName(tmpEditName)
                        }
                        list[index].name = tmpEditName
                        musicListStore.setValue('list', [...list])
                        setEditNameIndex(-1)
                      }
                    }}
                  />
                ) : (
                  song.name
                )}
              </div>{' '}
              <div className={style['song-time']}>
                {(song.playerTime / 1000).toFixed(1)}s
              </div>
            </div>
            <div className={style['buttons']}>
              {isActive(song) && (
                <button
                  className={style['song-stop']}
                  onClick={() => stopPusicSong(index)}>
                  <div className={style['inner']}></div>
                </button>
              )}
              {isActive(song) && (
                <button
                  className={style['song-play']}
                  onClick={() => {
                    if (playerSongController.current == null) {
                      console.error('playerSongController.current is null')
                    }
                    if (!isPause) {
                      playerSongController.current?.pause()
                      setIsPause(true)
                    } else {
                      playerSongController.current?.replay()
                      setIsPause(false)
                    }
                  }}>
                  <img
                    style={{
                      transform: `scale(${isPause ? 1 : 1.5})`,
                    }}
                    className={style['inner']}
                    src={isPause ? playSvg.src : pauseSvg.src}></img>
                </button>
              )}
              {!isActive(song) && (
                <button
                  className={style['song-play']}
                  onClick={() => playerPusicSong(index)}>
                  <img className={style['inner']} src={playSvg.src}></img>
                </button>
              )}
              <button
                className={style['song-play']}
                onClick={() => showMoreContextMenu(index)}>
                <img
                  className={style['inner']}
                  style={{ transform: 'scale(1.8)' }}
                  src={moreSvg.src}></img>
              </button>
            </div>

            {isActive(song) && (
              <ProgressBar
                style={{
                  position: 'absolute',
                  left: 0,
                  bottom: 0,
                }}
                onChange={(value, isDrag) => {
                  if (isDrag) {
                    return
                  }
                  if (playerSongController.current == null) {
                    console.warn('playerSongController.current is null')
                    return
                  }
                  const isPause = playerSongController.current.isPause
                  if (isPause) {
                    playerSongController.current.currentTime =
                      playerSongController.current.allTime * value
                    setPlayerProgress(value)
                    return
                  }
                  playerSongController.current.pause()
                  playerSongController.current.currentTime =
                    playerSongController.current.allTime * value
                  setPlayerProgress(value)
                  playerSongController.current.replay()
                }}
                progress={playerProgress}
              />
            )}
          </div>
        )
      })}
    </div>
  )
}
export default observer(SongList)
